diff --git a/swh/web/ui/static/css/style.css b/swh/web/ui/static/css/style.css --- a/swh/web/ui/static/css/style.css +++ b/swh/web/ui/static/css/style.css @@ -28,4 +28,39 @@ .file-found { color: #23BA49; } .file-notfound { color: #FF4747; } + +/* Bootstrap custom styling */ +.input-group-field { + display: table-cell; + vertical-align: middle; + border-radius:4px; + min-width:1%; + white-space: nowrap; +} + +.input-group-field .form-control { + border-radius: inherit !important; +} + +.input-group-field:not(:first-child):not(:last-child) { + border-radius:0; +} + +.input-group-field:not(:first-child):not(:last-child) .form-control { + border-left-width: 0; + border-right-width: 0; +} + +.input-group-field:last-child { + border-top-left-radius:0; + border-bottom-left-radius:0; +} + +.input-group > span:not(:last-child) > button { + border-radius: 0; +} + +.multi-input-group > .input-group-btn { + vertical-align: bottom; + padding: 0; } \ No newline at end of file diff --git a/swh/web/ui/templates/api.html b/swh/web/ui/templates/api.html --- a/swh/web/ui/templates/api.html +++ b/swh/web/ui/templates/api.html @@ -1,5 +1,5 @@ {% extends "layout.html" %} -{% block title %}Software Heritage API Overview{% endblock %} +{% block title %}API Overview{% endblock %} {% block content %} <div class="api-doc"> {% for route, doc in doc_routes %} diff --git a/swh/web/ui/templates/browse.html b/swh/web/ui/templates/browse.html new file mode 100644 --- /dev/null +++ b/swh/web/ui/templates/browse.html @@ -0,0 +1,56 @@ +{% extends "layout.html" %} +{% block title %}Browse{% endblock %} +{% block content %} + +<div class="browse-panel panel panel-default"> + <div class="panel panel-body"> + + <ul class="nav nav-tabs" role="tablist"> + <li><a class="nav-link active" data-toggle="tab" href="#tab-content" role="tabpanel">Content</a></li> + <li><a class="nav-link" data-toggle="tab" href="#tab-revision" role="tabpanel">Revision</a></li> + <li><a class="nav-link" data-toggle="tab" href="#tab-origin" role="tabpanel">Origin</a></li> + <li><a class="nav-link" data-toggle="tab" href="#tab-directory" role="tabpanel">Directory</a></li> + </ul> + + <div class="tab-content container-fluid"> + <!-- Content pane --> + <div class="tab-pane active" id="tab-content" role="tabpanel"> + <div class="row simple-desc container-fluid"> + You can refer to a content (i.e. a file that we have in our database) as its SHA1 or SHA256 + checksum. If you have files to input, you can drag and drop them below to have their hashes + calculated and searched in SWH. Files with the same checksum will automatically be ignored. + </div> + <div class="row container-fluid"> + {% include 'includes/search-form.html' %} + </div> + </div> + + <!-- Revision pane --> + <div class="tab-pane" id="tab-revision" role="tabpanel"> + {% include 'includes/home-revision.html' %} + </div> + + <!-- Origin pane --> + <div class="tab-pane" id="tab-origin" role="tabpanel"> + {% include 'includes/home-origin.html' %} + </div> + + <!-- Directory pane --> + <div class="tab-pane" id="tab-directory" role="tabpanel"> + {% include 'includes/home-directory.html' %} + </div> + </div> + + </div> +</div> + +<script> + // Hash update on page load + var hash = window.location.hash; + hash && $('ul.nav a[href="' + hash + '"]').tab('show'); + // Hash update on nav-tab click + $('.nav-tabs a').click(function(e) { + window.location.hash = this.hash; + }) +</script> +{% endblock %} diff --git a/swh/web/ui/templates/home.html b/swh/web/ui/templates/home.html --- a/swh/web/ui/templates/home.html +++ b/swh/web/ui/templates/home.html @@ -1,9 +1,12 @@ {% extends "layout.html" %} {% block title %}Home{% endblock %} {% block content %} + <ul> - <li><a href="/about">About</a></li> - <li><a href="/search">Search</a></li> - <li><a href="/browse/directory">Browse directory</a></li> + <li><a href="{{ url_for('about') }}">About</a></li> + <li><a href="https://www.softwareheritage.org">Main site</a></li> + <li><a href="{{ url_for('browse') }}">Browse</a></li> + <li><a href="{{ url_for('browse_api_doc') }}">API</a></li> </ul> + {% endblock %} diff --git a/swh/web/ui/templates/includes/home-directory.html b/swh/web/ui/templates/includes/home-directory.html new file mode 100644 --- /dev/null +++ b/swh/web/ui/templates/includes/home-directory.html @@ -0,0 +1,111 @@ +<div class="simple-search"> + <div class="row simple-desc container-fluid"> + Search a directory according to its SHA1 checksum + </div> + <form method="get" action="{{ url_for('search_directory') }}"> + <div class="row"> + <div class="col-md-6 required"> + <label for="dir-sha1">Directory ID</label> + <div class="input-group"> + <input id="dir-sha1" class="form-control" + type="text" placeholder="directory git SHA1" + name="sha1_git" required="true"/> + <span class="input-group-btn"> + <button class="btn btn-primary" type="submit"> + <span class="glyphicon glyphicon-search" aria-hidden="true"></span> + </button> + </span> + <a class="input-group-addon" data-toggle="collapse" href="#dir-dir-collapse">Options</a> + </div> + </div> + <div class="col-md-6"> + <div id="dir-dir-collapse" class="collapse"> + <label for="dir-path-1">Path within directory</label> + <input id="dir-path-1" class="optional form-control" + type="text" placeholder="path" name="path/"> + </div> + </div> + </div> + </form> +</div> +<hr/> +<div class="text-center"> + <a data-toggle="collapse" href="#dir-advanced-search">Advanced search</a> +</div> +<div id="dir-advanced-search" data-toggle="collapse" class="collapse advanced-search"> + <div class="row advanced-desc container-fluid"> + You can also refer to a directory either: + <ul> + <li> + as a request for the content of a revision identified in absolute + terms by its git SHA1. + </li> + <li> + as a request for the content of a revision matching a + given time and place, with place the origin of the directory (and optionally its + branch name), and time a timestamp of when we collected it (or as close to the + timestamp as we can provide). + </li> + </ul> + In all cases, you may also specify a path within the top-level directory to which you + would like the results to be constrained. + </div> + <div> + <form method="get" action="{{ url_for('search_directory') }}"> + <div class="forms-group row"> + <div class="col-md-6 required"> + <label for="dir-rev-sha1">Revision ID</label> + <div class="input-group"> + <input id="dir-rev-sha1" class="form-control" + type="text" placeholder="revision git SHA1" + name="sha1_git" required="true"/> + <span class="input-group-btn"> + <button class="btn btn-primary" type="submit"> + <span class="glyphicon glyphicon-search" aria-hidden="true"></span> + </button> + </span> + <a class="input-group-addon" data-toggle="collapse" href="#dir-rev-collapse">Options</a> + </div> + </div> + <div class="col-md-6"> + <div id="dir-rev-collapse" class="collapse"> + <label for="dir-path-2">Path within directory</label> + <input id="dir-path-2" class="optional form-control" + type="text" placeholder="path" name="dir_path"/> + </div> + </div> + </div> + </form> + <form method="get" action="{{ url_for('search_directory') }}"> + <div class="form-groups row"> + <div class="col-md-6"> + <label for="dir-origin-id">Origin ID</label> + <div class="input-group"> + <input id="dir-origin-id" class="form-control" + type="text" placeholder="origin id" + name="origin_id" required="true"/> + <span class="input-group-btn"> + <button class="btn btn-primary" type="submit"> + <span class="glyphicon glyphicon-search" aria-hidden="true"></span> + </button> + </span> + <a class="input-group-addon" data-toggle="collapse" href="#dir-origin-collapse">Options</a> + </div> + </div> + <div class="col-md-6"> + <div id="dir-origin-collapse" class="collapse"> + <label for="dir-branchname">Branch name</label> + <input id="dir-branchname" class="optional form-control" + type="text" placeholder="refs/heads/master" name="branch_name"/> + <label for="dir-timestamp">Timestamp</label> + <input id="dir-timestamp" class="optional form-control" + type="text" placeholder="timestamp" name="ts"/> + <label for="dir-path-3">Path within the directory</label> + <input id="dir-path-3" class="optional form-control" + type="text" placeholder="path" name="path"/> + </div> + </div> + </div> + </form> + </div> +</div> diff --git a/swh/web/ui/templates/includes/home-origin.html b/swh/web/ui/templates/includes/home-origin.html new file mode 100644 --- /dev/null +++ b/swh/web/ui/templates/includes/home-origin.html @@ -0,0 +1,57 @@ +<div class="simple-search"> + <div class="row simple-desc container-fluid"> + Search an origin according to its SWH ID + </div> + <form method="get" action="{{ url_for('search_directory') }}"> + <div class="row"> + <div class="col-md-12"> + <label>Origin ID</label> + <div class="input-group"> + <input class="form-control" type="text" placeholder="directory git SHA1" name="sha1_git" required="true"/> + <span class="input-group-btn"> + <button class="btn btn-primary" type="submit"> + <span class="glyphicon glyphicon-search" aria-hidden="true"></span> + </button> + </span> + </div> + </div> + </div> + </form> +</div> +<hr/> +<div class="text-center"> + <a data-toggle="collapse" href="#origin-advanced-search">Advanced search</a> +</div> +<div id="origin-advanced-search" data-toggle="collapse" class="collapse advanced-search"> + <div class="row advanced-desc container-fluid"> + You can also refer to a directory in a relative manner, as the combination of the type of origin (git, debian, tarball...) + and the URL at which the origin is located. + </div> + <div> + <form method="get" action="{{ url_for('search_origin') }}"> + <div class="forms-group row"> + <div class="col-md-12"> + <div class="input-group multi-input-group"> + <label for="origin-type">Origin type</label> + <input id="origin-type" + class="form-control" + type="text" placeholder="origin type" + name="origin_type" required="true"/> + <div class="input-group-field"> + <label for="origin-url">Origin URL</label> + <input id="origin-url" + class="form-control" + type="text" placeholder="origin url" + name="origin_url" required="true"/> + </div> + <span class="input-group-btn"> + <button id="origin-dummy-btn" class="btn btn-primary" type="submit"> + <span class="glyphicon glyphicon-search" aria-hidden="true"></span> + </button> + </span> + </div> + </div> + </div> + </form> + </div> +</div> diff --git a/swh/web/ui/templates/includes/home-revision.html b/swh/web/ui/templates/includes/home-revision.html new file mode 100644 --- /dev/null +++ b/swh/web/ui/templates/includes/home-revision.html @@ -0,0 +1,66 @@ +<div class="simple-search"> + <div class="row simple-desc container-fluid"> + Search a revision according to its SHA1 identifier + </div> + <form method="get" action="{{ url_for('search_revision') }}"> + <div class="row"> + <div class="col-md-12"> + <label for="rev-sha1">Revision SHA1</label> + <div class="input-group"> + <input id="rev-sha1" class="form-control" + type="text" placeholder="git SHA1" + name="sha1_git" required="true"/> + <span class="input-group-btn"> + <button class="btn btn-primary" type="submit"> + <span class="glyphicon glyphicon-search" aria-hidden="true"></span> + </button> + </span> + </div> + </div> + </div> + </form> +</div> +<hr/> +<div class="text-center"> + <a data-toggle="collapse" href="#rev-advanced-search">Advanced search</a> +</div> +<div id="rev-advanced-search" data-toggle="collapse" class="collapse advanced-search"> + <div class="row advanced-desc container-fluid"> + You can also refer to a revision as an SWH time and place, time being a timestamp of when we + collected it (or as close to the timestamp as we can provide), place being an origin, and + optionally a branch name within the origin. See the origin section to search for origins in + SWH and find out their identifier. + </div> + <div> + <form method="get" action="{{ url_for('search_revision') }}"> + <div class="forms-group row"> + <div class="col-md-6 required"> + <label>Revision Origin ID</label> + <div class="input-group"> + <input class="form-control" type="text" placeholder="revision git SHA1" name="sha1_git" required="true"/> + <span class="input-group-btn"> + <button class="btn btn-primary" type="submit"> + <span class="glyphicon glyphicon-search" aria-hidden="true"></span> + </button> + </span> + <a class="input-group-addon" data-toggle="collapse" href="#rev-tandp-collapse">Options</a> + </div> + </div> + <div class="col-md-6"> + <div id="rev-tandp-collapse" class="collapse"> + <label for="rev-branchname">Branch name</label> + <input id="rev-branchname" + class="optional form-control" + type="text" placeholder="refs/heads/master" + name="branch_name"/> + <label for="rev-timestamp">Timestamp</label> + <input id="rev-timestamp" + class="optional form-control" + type="text" placeholder="timestamp" + name="ts"/> + </div> + </div> + </div> + </form> + </div> +</div> diff --git a/swh/web/ui/templates/search-form.html b/swh/web/ui/templates/includes/search-form.html rename from swh/web/ui/templates/search-form.html rename to swh/web/ui/templates/includes/search-form.html --- a/swh/web/ui/templates/search-form.html +++ b/swh/web/ui/templates/includes/search-form.html @@ -1,5 +1,5 @@ <!-- The text-based SHA1 or SHA256 search --> -<h2>Search with SHA-1 or SHA-256:</h2> +<label for="text-hash-form">Search with SHA-1 or SHA-256:</label> <form id="text-hash-form" action="{{ url_for('search_content') }}" class="form" @@ -7,21 +7,21 @@ <br/> <div class="input-group"> <input id="text-hash-input" - type="text" class="form-control" - name="q" - placeholder="SHA-1 or SHA-256 checksum" /> + type="text" class="form-control" + name="q" + placeholder="SHA-1 or SHA-256 checksum" /> <span class="input-group-btn"> <button id="text-hash-submit" - class="btn btn-primary" - type="submit"> - Text search + class="btn btn-primary" + type="submit"> + Text search </button> </span> </div> </form> <!-- The file-based drag&drop UI--> -<h2>Search with files</h2> +<label for="file-hash-form">Search with files</label> <form id="file-hash-form" action="{{ url_for('search_content') }}" class="text-center form" @@ -30,13 +30,13 @@ <!--Form input --> <input type="file" - id="file-hash-input" - class="form-control" - multiple - name="filename" - value="" - style="display:none" - placeholder="File(s) to hash and search" /> + id="file-hash-input" + class="form-control" + multiple + name="filename" + value="" + style="display:none" + placeholder="File(s) to hash and search" /> <div id="file-drop" class="text-center" style="border: 1px dashed black"> Drag and drop or click here to hash files and search for them. Your files will NOT be uploaded, hashing is done locally. @@ -58,15 +58,13 @@ </form> <!-- Required JS --> -<script src="{{ url_for('static', filename='lib/core.js') }}"></script> -<script src="{{ url_for('static', filename='lib/lib-typedarrays.js') }}"></script> -<script src="{{ url_for('static', filename='lib/sha1.js') }}"></script> -<script src="{{ url_for('static', filename='lib/sha256.js') }}"></script> -<script src="{{ url_for('static', filename='js/search.js') }}"></script> +{% for fname in ['lib/core.js', 'lib/lib-typedarrays.js', 'lib/sha1.js', 'lib/sha256.js', 'js/search.js'] %} +<script language="javascript" type="text/javascript" src="{{ url_for('static', filename=fname) }}"></script> +{% endfor %} <!-- Script setup --> <script> - var sfc = new SearchFormController($('#text-hash-form'), $('#file-hash-form'), $('#search-message')); + var sfc = new SearchFormController($('#text-hash-form'), $('#file-hash-form'), $('#search-message')); sfc.setupTextForm($('#text-hash-input')); sfc.setupFileForm($('#file-drop'),$('#filelist'),$('#file-hash-input'),$('#file-hash-clear')); </script> diff --git a/swh/web/ui/templates/layout.html b/swh/web/ui/templates/layout.html --- a/swh/web/ui/templates/layout.html +++ b/swh/web/ui/templates/layout.html @@ -1,37 +1,57 @@ <!DOCTYPE html> <html lang="en"> -<head> - <meta charset="utf-8"> - <meta http-equiv="X-UA-Compatible" content="IE=edge"> - <meta name="viewport" content="width=device-width, initial-scale=1"> - <title>{% block title %}{% endblock %} - The Software Heritage Archive</title> - <!-- BEGIN: bootstrap --> - <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" integrity="sha512-dTfge/zgoMYpP7QbHy4gWMEGsbsdZeCXz7irItjcC3sPUFtf0kuFbDz/ixG7ArTxmDjLXDmezHubeNikyKGVyQ==" crossorigin="anonymous"> - <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css" integrity="sha384-aUGj/X2zp5rLCbBxumKTCw2Z50WgIr1vs/PFN4praOTvYXWlVyh2UtNUU0KAUhAX" crossorigin="anonymous"> - <link rel="stylesheet" href="{{ url_for('static', filename='css/bootstrap-responsive.min.css') }}"> - <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> - <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js" integrity="sha512-K1qjQ+NcF2TYO/eI3M6v8EiNYZfA95pQumfvcVrTHtwQVDG+aHRqLi/ETn2uB+1JqwYqVG3LIvdm9lj6imS/pQ==" crossorigin="anonymous"></script> - <!-- END: bootstrap --> - <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/style.css') }}" /> - <script>document.domain = "softwareheritage.org";</script> -</head> -<body> - <div class="jumbotron"> - <div class="container"> - <h1>{{ self.title() }}</h1> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <title>{% block title %}{% endblock %} - The Software Heritage Archive</title> + <!-- BEGIN: bootstrap --> + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" integrity="sha512-dTfge/zgoMYpP7QbHy4gWMEGsbsdZeCXz7irItjcC3sPUFtf0kuFbDz/ixG7ArTxmDjLXDmezHubeNikyKGVyQ==" crossorigin="anonymous"> + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css" integrity="sha384-aUGj/X2zp5rLCbBxumKTCw2Z50WgIr1vs/PFN4praOTvYXWlVyh2UtNUU0KAUhAX" crossorigin="anonymous"> + <link rel="stylesheet" href="{{ url_for('static', filename='css/bootstrap-responsive.min.css') }}"> + <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js" integrity="sha512-K1qjQ+NcF2TYO/eI3M6v8EiNYZfA95pQumfvcVrTHtwQVDG+aHRqLi/ETn2uB+1JqwYqVG3LIvdm9lj6imS/pQ==" crossorigin="anonymous"></script> + <!-- END: bootstrap --> + <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/style.css') }}" /> + <script>document.domain = "softwareheritage.org";</script> + </head> + <body> + <div class="jumbotron"> + <div class="container"> + <h1>{{ self.title() }}</h1> + <nav class="navbar navbar-default"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle collapsed" + data-toggle="collapse" data-target="#swh-navbar-collapse" aria-expanded="false"> + </button> + <a class="navbar-brand" href="{{ url_for('homepage') }}">SWH Archive</a> + </div> + + <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> + <ul class="nav navbar-nav"> + <li><a href="https://www.softwareheritage.org">Main site</a></li> + <li role="separator" class="divider"></li> + <li><a href="{{ url_for('browse') }}">Browse</a></li> + <li role="separator" class="divider"></li> + <li><a href="{{ url_for('browse_api_doc') }}">API</a></li> + <li role="separator" class="divider"></li> + <li><a href="{{ url_for('about') }}">About</a></li> + </ul> + </div> + </nav> + </div> </div> - </div> - {% with messages = get_flashed_messages(with_categories=true) %} + {% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} - <div class="container messages"> - {% for category, message in messages %} - <div class="alert alert-{{ category }}" role="alert">{{ message }}</div> - {% endfor %} - </div> + <div class="container messages"> + {% for category, message in messages %} + <div class="alert alert-{{ category }}" role="alert">{{ message }}</div> + {% endfor %} + </div> {% endif %} - {% endwith %} - <div class="container content"> - {% block content %}{% endblock %} - </div> -</body> + {% endwith %} + <div class="container content"> + {% block content %}{% endblock %} + </div> + </body> </html> diff --git a/swh/web/ui/templates/origin.html b/swh/web/ui/templates/origin.html --- a/swh/web/ui/templates/origin.html +++ b/swh/web/ui/templates/origin.html @@ -3,38 +3,46 @@ {% block content %} {% if message is not none %} - {{ message }} +{{ message }} {% endif %} {% if origin is not none %} -<script language="javascript" type="text/javascript" src="{{ url_for('static', filename='js/calendar.js') }}"></script> -<script language="javascript" type="text/javascript" src="{{ url_for('static', filename='lib/jquery.flot.min.js') }}"></script> -<script language="javascript" type="text/javascript" src="{{ url_for('static', filename='lib/jquery.flot.time.min.js') }}"></script> -<script language="javascript" type="text/javascript" src="{{ url_for('static', filename='lib/jquery.flot.selection.min.js') }}"></script> -<script language="javascript" type="text/javascript" src="{{ url_for('static', filename='lib/jquery.flot.tooltip.min.js') }}"></script> -<div> Details on origin {{ origin['id'] }}: - <div id="swh-calendar" style="height: 200px"> - <div id="cal-zoom-window" style="height: 60%"> - </div> - <div id="cal-static-window" style="height: 40%"> - </div> + +<!-- Flot plugin dependencies --> +{% for fname in ['js/calendar.js', 'lib/jquery.flot.min.js', 'lib/jquery.flot.time.min.js', 'lib/jquery.flot.selection.min.js', 'lib/jquery.flot.tooltip.min.js'] %} +<script language="javascript" type="text/javascript" src="{{ url_for('static', filename=fname) }}"></script> +{% endfor %} + +<!-- Timeline result --> +<h2>Origin visit history</h2> +<div class="timeline"> + <div id="swh-calendar-window" style="height: 200px"> + <div id="cal-zoom-window" style="height: 60%"></div> + <div id="cal-static-window" style="height: 40%"></div> </div> <button id="cal-clear">Reset</button> - {% for key in ['type', 'lister', 'project', 'url'] %} - {% if origin[key] is not none %} - <div class="row"> - <div class="col-md-2">{{ key }}</div> - <div class="col-md-6">{{ origin[key] }}</div> - </div> - {% endif %} - {% endfor %} - {% if 'decoding_failures' in content %} - <div class="row"> - <div class="col-md-10">(some decoding errors)</div> - </div> - {% endif %} </div> - <script>$(function(){var cal = new Calendar('{{ browse_url }}', '{{ visit_url }}', {{ origin['id'] }}, $('#cal-zoom-window'), $('#cal-static-window'), $('#cal-clear'));});</script> + +<!-- Data result --> +<h2>Origin information</h2> +<div> Details on origin {{ origin['id'] }}: + {% for key in ['type', 'lister', 'project', 'url'] %} + {% if origin[key] is not none %} + <div class="row"> + <div class="col-md-2">{{ key }}</div> + <div class="col-md-6">{{ origin[key] }}</div> + </div> + {% endif %} + {% endfor %} + {% if 'decoding_failures' in content %} + <div class="row"> + <div class="col-md-10">(some decoding errors)</div> + </div> + {% endif %} +</div> + +<!-- Flot calendar setup --> +<script>$(function(){var cal = new Calendar('{{ browse_url }}', '{{ visit_url }}', {{ origin['id'] }}, $('#cal-zoom-window'), $('#cal-static-window'), $('#cal-clear'));});</script> {% endif %} {% endblock %} diff --git a/swh/web/ui/templates/search.html b/swh/web/ui/templates/search.html --- a/swh/web/ui/templates/search.html +++ b/swh/web/ui/templates/search.html @@ -4,7 +4,7 @@ <div class="container"> <!-- Include the predefined search form--> - {% include 'search-form.html' %} + {% include 'includes/search-form.html' %} {% if search_res is not none %} <!-- Search result display --> diff --git a/swh/web/ui/tests/views/test_browse.py b/swh/web/ui/tests/views/test_browse.py --- a/swh/web/ui/tests/views/test_browse.py +++ b/swh/web/ui/tests/views/test_browse.py @@ -19,6 +19,39 @@ self.filename = filename +class StaticViews(test_app.SWHViewTestCase): + render_template = False + + @patch('swh.web.ui.apidoc.APIUrls') + @istest + def browse_api_doc(self, mock_api_urls): + # given + endpoints = { + '/a/doc/endpoint/': 'relevant documentation', + '/some/other/endpoint/': 'more docstrings'} + mock_api_urls.apidoc_routes = endpoints + + # when + rv = self.client.get('/api/') + + # then + self.assertEquals(rv.status_code, 200) + self.assertIsNotNone( + self.get_context_variable('doc_routes'), + sorted(endpoints.items()) + ) + self.assert_template_used('api.html') + + @istest + def browse_archive(self): + # when + rv = self.client.get('/browse/') + + # then + self.assertEquals(rv.status_code, 200) + self.assert_template_used('browse.html') + + class SearchRedirectsView(test_app.SWHViewTestCase): render_template = False @@ -116,26 +149,6 @@ class SearchView(test_app.SWHViewTestCase): render_template = False - @patch('swh.web.ui.apidoc.APIUrls') - @istest - def browse_api_doc(self, mock_api_urls): - # given - endpoints = { - '/a/doc/endpoint/': 'relevant documentation', - '/some/other/endpoint/': 'more docstrings'} - mock_api_urls.apidoc_routes = endpoints - - # when - rv = self.client.get('/api/1/doc/') - - # then - self.assertEquals(rv.status_code, 200) - self.assertIsNotNone( - self.get_context_variable('doc_routes'), - sorted(endpoints.items()) - ) - self.assert_template_used('api.html') - @istest def search_default(self): # when diff --git a/swh/web/ui/tests/views/test_main.py b/swh/web/ui/tests/views/test_main.py --- a/swh/web/ui/tests/views/test_main.py +++ b/swh/web/ui/tests/views/test_main.py @@ -5,30 +5,20 @@ from nose.tools import istest -from unittest.mock import patch - from .. import test_app class MainViewTestCase(test_app.SWHViewTestCase): render_template = False - @patch('flask.flash') @istest - def homepage(self, mock_flash): - # given - mock_flash.return_value = 'something' - + def homepage(self): # when rv = self.client.get('/') # then - self.assertEquals(rv.status_code, 200) - self.assert_template_used('home.html') - - mock_flash.assert_called_once_with( - 'This Web app is still work in progress, use at your own risk', - 'warning') + self.assertEquals(rv.status_code, 302) + self.assertRedirects(rv, '/browse/') @istest def info(self): diff --git a/swh/web/ui/views/browse.py b/swh/web/ui/views/browse.py --- a/swh/web/ui/views/browse.py +++ b/swh/web/ui/views/browse.py @@ -118,7 +118,14 @@ return render_template('search.html', **env) -@app.route('/api/1/doc/') +@app.route('/browse/') +def browse(): + """Render the user-facing browse view + """ + return render_template('browse.html') + + +@app.route('/api/') def browse_api_doc(): """Render the API's documentation. """ diff --git a/swh/web/ui/views/main.py b/swh/web/ui/views/main.py --- a/swh/web/ui/views/main.py +++ b/swh/web/ui/views/main.py @@ -13,9 +13,7 @@ """Home page """ - flask.flash('This Web app is still work in progress, use at your own risk', - 'warning') - return flask.render_template('home.html') + return flask.redirect(flask.url_for('browse')) @app.route('/about/')